package com.fadadianqi.logistics.admin.controller;

import com.fadadianqi.logistics.admin.controller.VillageController.VillageVO;
import com.fadadianqi.logistics.admin.staff.controller.MasterHelper;
import com.fadadianqi.logistics.admin.staff.service.ActionEnum;
import com.fadadianqi.logistics.admin.staff.service.MasterService;
import com.fadadianqi.logistics.customer.model.Customer;
import com.fadadianqi.logistics.customer.model.Town;
import com.fadadianqi.logistics.customer.model.Village;
import com.fadadianqi.logistics.customer.service.CustomerService;
import com.fadadianqi.logistics.search.CustomerSearcher;
import com.fadadianqi.search.Result;
import com.yeqiangwei.commons.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.support.SessionStatus;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.fadadianqi.logistics.admin.controller.URIMappingUtils.INVENTORY_PREFIX;

@Controller
public class CustomerController {

    private static final String URI_AJAX_VILLAGE_LIST = INVENTORY_PREFIX + "/ajax/village/list";

    private static final String VIEW_VILLAGE_LIST = "admin/village/list";

    private static final String VIEW_CUSTOMER_LIST = "admin/customer/list";
    private static final String VIEW_CUSTOMER_FORM = "admin/customer/form";

    private static final int MAX_RESULTS = 20;

    @RequestMapping(value = "/a/customer/save", method = RequestMethod.POST)
    public String save(@ModelAttribute("form") CustomerForm form,
                       BindingResult result, SessionStatus status
            , HttpServletRequest request, HttpServletResponse response
            , ModelMap modelMap) {

        if (ValidatorHelper.isEmpty(form.getName())) {
            result.rejectValue("name", "remind.required.name");
        }

        Village village = customerService.getVillageById(form.getVillageId());
        if (village == null) {
            result.rejectValue("villageId", "remind.required.village");
        }
        if (result.hasErrors()) {
            modelMap.put("villageVOList", getVillageVOList());
            return VIEW_CUSTOMER_FORM;
        }
        Customer customer = new Customer();
        BeanUtils.copyProperties(customer, form);

        Double balance = 0D;
        Double debt = 0D;
        if (ValidatorHelper.isNotEmpty(form.getId())) {
            Customer buf = customerService.getById(form.getId());
            if (buf != null) {
                balance = buf.getBalance();
                debt = buf.getDebt();
            }
        }
        MasterHelper.getMaster(request);
        if (!masterService.hasPermission(MasterHelper.getMaster(request)
                , ActionEnum.CUSTOMER_BALANCE_MODIFY)) {
            customer.setBalance(balance);
        }
        if (!masterService.hasPermission(MasterHelper.getMaster(request)
                , ActionEnum.CUSTOMER_DEBT_MODIFY)) {
            customer.setDebt(debt);
        }
        Town town = customerService.getTownById(village.getTownId());
        customer.setTownId(town.getId());
        customerService.saveCustomer(customer);

        saveVillageIdBuf(request, response, customer.getVillageId());

        return "redirect:/a/customer/list?villageId=" + village.getId();
    }

    @RequestMapping(value = INVENTORY_PREFIX + "/customer/form", method = RequestMethod.GET)
    public String showForm(HttpServletRequest request, ModelMap modelMap) {
        String id = ParamUtils.getString(request, "id", null);
        Customer customer = customerService.getById(id);
        CustomerForm form = new CustomerForm();
        if (customer != null) {
            BeanUtils.copyProperties(form, customer);
        }
        modelMap.put("form", form);
        String villageIdBuf = form.getVillageId();
        if (ValidatorHelper.isEmpty(villageIdBuf)) {
            villageIdBuf = getVillageIdBuf(request);
        }
        modelMap.put("villageId", villageIdBuf);
        Village village = customerService.getVillageById(villageIdBuf);
        modelMap.put("village", village);
        return VIEW_CUSTOMER_FORM;
    }

    @RequestMapping(value = INVENTORY_PREFIX + "/customer/search", method = RequestMethod.GET)
    public String search(HttpServletRequest request, ModelMap modelMap) {
        String q = ParamUtils.getString(request, "q", null);
        if (q == null) {
            return showList(request, modelMap);
        }
        modelMap.put("q", q);
        Pagination pagination = new Pagination(request, MAX_RESULTS);
        Result result = null;
        try {
            result = customerSearcher.search(q, pagination);
        } catch (Exception e) {
            e.printStackTrace();
        }
        List<Customer> customerVOList = new ArrayList<Customer>();
        if (result.getItems() != null && result.getItems().size() > 0) {
            List<?> list = result.getItems();
            for (Object o : list) {
                CustomerSearcher.CustomerVO
                        _customer = (CustomerSearcher.CustomerVO) o;
                Customer customer = customerService.getById(_customer.getId());
                CustomerVO vo = new CustomerVO();
                BeanUtils.copyProperties(vo, customer);
                Village village = customerService.getVillageById(customer.getVillageId());
                vo.setTown(customerService.getTownById(village.getTownId()));
                vo.setVillage(village);
                customerVOList.add(vo);
            }
            pagination.setTotal(result.getTotal());
            Map<String, Object> elements = new HashMap<String, Object>();
            elements.put("q", q);
            pagination.setElements(elements);
            PaginationHelper.setAttribute(request, pagination);
            modelMap.put("customerVOList", customerVOList);
        }
        modelMap.put("villageVOList", getVillageVOList());
        return VIEW_CUSTOMER_LIST;
    }

    @RequestMapping(value = INVENTORY_PREFIX + "/customer/list", method = RequestMethod.GET)
    public String showList(HttpServletRequest request, ModelMap modelMap) {

        String villageId = ParamUtils.getString(request, "villageId", null);
        Pagination pagination = new Pagination(request, MAX_RESULTS);
        Integer total;
        List<Customer> customerList = null;
        if (villageId == null) {
            customerList = customerService.findAll(pagination);
            total = customerService.countAll();
        } else {
            customerList = customerService.findAllByVillageId(villageId, pagination);
            total = customerService.countByVillageId(villageId);
            Map<String, Object> elements = new HashMap<String, Object>();
            elements.put("villageId", villageId);
            pagination.setElements(elements);
        }
        pagination.setTotal(total);
        PaginationHelper.setAttribute(request, pagination);
        if (ValidatorHelper.isNotEmpty(customerList)) {
            List<Customer> customerVOList = new ArrayList<Customer>();
            for (Customer customer : customerList) {
                CustomerVO vo = new CustomerVO();
                BeanUtils.copyProperties(vo, customer);
                Village village = customerService.getVillageById(customer.getVillageId());
                if (village != null) {
                    vo.setTown(customerService.getTownById(village.getTownId()));
                    vo.setVillage(village);
                }
                customerVOList.add(vo);
            }
            modelMap.put("customerVOList", customerVOList);
        }

        modelMap.put("villageVOList", getVillageVOList());

        return VIEW_CUSTOMER_LIST;
    }

    private List<VillageVO> getVillageVOList() {
        List<VillageVO> villageVOList = new ArrayList<VillageController.VillageVO>();
        List<Town> townList = customerService.findAllTown();
        for (Town town : townList) {
            VillageVO vo = new VillageVO();
            vo.setTown(town);

            List<Village> villageList = customerService.findAllVillage(town.getId());
            vo.setVillageList(villageList);

            villageVOList.add(vo);
        }
        return villageVOList;
    }

    @RequestMapping(value = URIMappingUtils.INVENTORY_PREFIX + URI_AJAX_VILLAGE_LIST
            , method = RequestMethod.GET)
    public String villageList(HttpServletRequest request, ModelMap modelMap) {
        String townId = ParamUtils.getString(request, Village.PROP_TOWN_ID, null);
        List<Village> villageList = customerService.findAllVillage(townId);
        List<Town> townList = customerService.findAllTown();
        modelMap.put("villageList", villageList);
        modelMap.put("townList", townList);
        return VIEW_VILLAGE_LIST;
    }

    private void saveVillageIdBuf(HttpServletRequest request
            , HttpServletResponse response, String villageId) {
        HttpCookieUtils.setValue(response, null, "villageIdBuf", villageId, 300);
    }

    private String getVillageIdBuf(HttpServletRequest request) {
        return HttpCookieUtils.getValue(request, "villageIdBuf", null);
    }

    @Autowired
    private CustomerService customerService;

    @Resource(name = "customerSearcher")
    private CustomerSearcher customerSearcher;

    @Autowired
    private MasterService masterService;

    public static class CustomerForm {

        private String id;
        private String name;
        private String mobile;
        private String tel;
        private String memo;
        private String villageId;
        private Double balance; // 个人存款
        private Double debt; // 个人债务

        public Double getBalance() {
            return balance;
        }

        public void setBalance(Double balance) {
            this.balance = balance;
        }

        public Double getDebt() {
            return debt;
        }

        public void setDebt(Double debt) {
            this.debt = debt;
        }

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getMobile() {
            return mobile;
        }

        public void setMobile(String mobile) {
            this.mobile = mobile;
        }

        public String getTel() {
            return tel;
        }

        public void setTel(String tel) {
            this.tel = tel;
        }

        public String getMemo() {
            return memo;
        }

        public void setMemo(String memo) {
            this.memo = memo;
        }

        public String getVillageId() {
            return villageId;
        }

        public void setVillageId(String villageId) {
            this.villageId = villageId;
        }
    }

    public static class CustomerVO extends Customer {

        /**
         *
         */
        private static final long serialVersionUID = -6153275087899994620L;

        private Town town;
        private Village village;

        public Town getTown() {
            return town;
        }

        public void setTown(Town town) {
            this.town = town;
        }

        public Village getVillage() {
            return village;
        }

        public void setVillage(Village village) {
            this.village = village;
        }
    }
}
